<?php 

namespace SDXApi\Controller;

use Think\Controller;

/**
 * 机器人推送接口
 * 
 * @author ^2_3^岑业宝
 *
 */
class RobotapiController extends Controller {
    
    // 报表路径
    private $url_report = "http://w.shidexian.com/index.php?m=admin&c=storewarn&a=index";

    // 预警库存数量
    private $default_num = 3;
    
    // webhook
    private $webhook = "https://oapi.dingtalk.com/robot/send?access_token=ed300402f93b76d152b1bad8f2869441ad52058f2303856c94a63b25c119cc74";
    
    // 定时报警时间
    private $timing_warn = '9:00,12:00,16:00';
    
    // 预警开始时间
    private $begin_time = '08:30';
    
    // 预警结束时间
    private $end_time = '19:00';
    
    // 监控仓库ID串
    private $str_wid = '8,17'; //高志大厦体验店,海珠体验店;
    
    // 预警开关(on开/off关)
    private $switch = 'on';

    // 仓库、机器人映射
    private $arr_robot = array(
        //-/ 高志体验店
        '8' => 'https://oapi.dingtalk.com/robot/send?access_token=14523ca1be4af0b9d44a24334af1f8dd0018b61092bdf1c123377793301cf9b1',
        //-/ 白云体验店
        '18' => 'https://oapi.dingtalk.com/robot/send?access_token=6874ba5a9f7a57870de342224f48a0e973e3f771e72d57f124e0d9b00e23328b',
        //-/ 海珠体验店
        '17' => 'https://oapi.dingtalk.com/robot/send?access_token=ee3d5a82359c3ba40793013a58e88c656a60108bcfa184b551d0d9fdb5e69654'
    );
    
    public function __construct() {
        parent::__construct();
    }
    
    /**
     * webhook机器人
     * http://apidev.cyb.cn/index.php?s=/robotapi/robot/
     * @author ^2_3^
     */
    public function robot() {
        set_time_limit(0);
        $start = microtime(true);
        $result = array();
        $result['status'] = 0;
        $result['msg'] = '';
        
        /// 默认设置
        $list_default = M('gstore_config')->where( array("set_type"=>0) )->select();
        foreach ( $list_default as $d_key=>$d_arr ) {
            switch ($d_arr['set_key']) {
                case 'default_num':
                    //-/ 预警库存数量
                    $default_num = $d_arr['set_val'];
                    break;
                case 'webhook':
                    //-/ 机器人webhook串
                    $webhook = $d_arr['set_val'];
                    break;
                case 'timing_warn':
                    //-/ 定时报警
                    $timing_warn = $d_arr['set_val'];
                    break;
                case 'begin_time':
                    //-/ 预警开始时间
                    $begin_time = $d_arr['set_val'];
                    break;
                case 'end_time':
                    //-/ 预警结束时间
                    $end_time = $d_arr['set_val'];
                    break;
                case 'str_wid':
                    $str_wid = $d_arr['set_val'];
                    break;
                case 'switch':
                    $switch = $d_arr['switch'];
                    break;
            }
        }
        empty($default_num) && $default_num = $this->default_num;
        empty($webhook) && $webhook = $this->webhook;
        empty($timing_warn) && $timing_warn = $this->timing_warn;
        empty($begin_time) && $begin_time = $this->begin_time;
        empty($end_time) && $end_time = $this->end_time;
        empty($str_wid) && $str_wid = $this->str_wid;
        empty($switch) && $switch = $this->switch;
        
        $str_time = date('H:i'); //10:30;
        /// 休息时段不预警
        if( $switch == 'off' || $str_time >= '23:00' || ($str_time >= '00:00' && $str_time <= '07:00') ) {
            $result['msg'] = '关闭/休息时段(23:00 - 07:00);';
            exit( json_encode($result) );
        }
        
        /// 过滤参数
        $filter['default_num'] = $default_num;
        $filter['str_wid'] = $str_wid;
        
        /// 定时报警(默认9:00,12:00,16:00)
        $arr_timing_warn = explode(',', $timing_warn);
        if( in_array($str_time, $arr_timing_warn) ) {
        
            /// SQL语句
            $arr_sql_timing = self::get_sql( $filter, 'timing_warn');
            $sql_count = $arr_sql_timing['sql_count_sum'];
// w_log('warn_log', $sql_count);
            //-/ 预警商品数量
            $list_timing = M()->query($sql_count);
            if( empty($list_timing) ) {
                $result['msg'] = '定时报警无数据;';
                exit( json_encode($result) );
            }

            //-/ 分仓库提醒信息
            $arr_wid_tip = array();

            //-/ 分仓库信息
            $str_tip = '';
            //-/ 汇总数量
            $num_goods = '';
            foreach ( $list_timing as $t_key=>$t_arr ) {
                $num_goods += $t_arr['count_num'];
                $str_tip .= "{$t_arr['wh_name']}[{$t_arr['count_num']}] + ";

                //-/ 分仓库提醒信息
                $arr_wid_tip[ $t_arr['wid'] ] = "{$t_arr['wh_name']}有{$t_arr['count_num']}个预警商品需要查看，请点击查看预警报表";
            }
            $str_tip = rtrim($str_tip, '+ ');
            $str_tip = "有{$num_goods}个预警商品({$str_tip})需要查看，请点击查看预警报表";
        
            /// 发送信息
            $flag_timing = self::dispose_post_data($webhook, $str_tip);
            if( $flag_timing ) {
                $result['status'] = 1;
                $result['msg'] .= "汇总信息发送成功；";

                /// 分仓库预警
                foreach ( $arr_wid_tip as $wkey=>$wvalue ) {
                    $wid_webhook = $this->arr_robot[ $wkey ];

                    $flag_w = self::dispose_post_data($wid_webhook, $wvalue);
                    $flag_w && $result['msg'] .= "{$wkey}仓库发送成功；";
                }

                //-/ 记录预警
//                 $sql_it = $arr_sql_timing['sql_it'];
//                 $flag_it = M()->execute($sql_it);
//                 if( $flag_it ) {
//                     $result['status'] = 1;
//                     $result['msg'] .= "信息记录成功;";
//                 }
            }
        
            /// 即时报警(分钟)
        } else {
            if( $str_time < $begin_time || $str_time > $end_time ) {
                $result['msg'] = "不在工作时段({$begin_time} - {$end_time});";
                exit( json_encode($result) );
            }
        
            /// 及时SQL语句
            $arr_warning = self::get_sql($filter, "timing_warn");
            $sql_warning = $arr_warning['sql_warning'];
            //-/ 列表
            $list_warning = M()->query( $sql_warning );
            if( count($list_warning) ) {
                //-/ 报表设置
                $url = $this->url_report;
        
                /// 预警个数
                $sql_count = $arr_warning['sql_count'];
                $arr_count = M()->query( $sql_count );
        
                /// 信息标题
                $str_tip = '';
                $arr_whname = array();
                foreach ($arr_count as $c_key=>$c_arr ) {
                    $arr_whname[$c_arr['wid']]["wh_name"] = $c_arr['wh_name'];
                    $arr_whname[$c_arr['wid']]["count_num"] = $c_arr['count_num'];
                    $str_tip .= "{$c_arr['wh_name']}有{$c_arr['count_num']}个预警商品; ";
                }
                $str_tip .= "\n";
        
                /// 信息列表
                foreach ( $list_warning as $l_key=>$l_arr ){
                    $arr_whname[$l_arr['wid']]["list"][] = $l_arr;
                }
                foreach ( $arr_whname as $aw_key=>$aw_arr ){
                    $str_tip .= "> [{$aw_arr['wh_name']}]({$url}&warehouse[0]={$aw_key})\n\n";
                    foreach ( $aw_arr['list'] as $g_key=>$g_arr ){
                        $g_key = $g_key+1;
                        if( $g_key <= 10 ) {
                            $str_tip .= ">序号{$g_key}   {$g_arr['goods_name']}  {$g_arr['goods_sn']}    库存量{$g_arr['store_num']}\n\n";
                        }else {
                            $num_more = $aw_arr['count_num'] - 10;
                            $str_tip .= ">...(还有{$num_more}个商品~)\n\n";
                            break;
                        }
        
                    }
                }
        
                /// 信息发送
                $flag_timing = self::dispose_post_data($webhook, $str_tip, 'markdown');
                if( $flag_timing ) {
                    $result['msg'] .= "信息记录成功; ";
        
                    /// 添加数据
                    $sql_it = $arr_warning['sql_it'];
                    $flag_it = M()->execute( $sql_it );
                    if( $flag_it ) {
                        $result['msg'] .= "汇总预警记录成功；";
                        $result['status'] = 1;
                    }

                    /// 分发仓库信息
                    foreach ( $arr_whname as $w_key=>$w_arr ) {
                        $msg_tip = '';
                        $msg_tip .= "{$w_arr['wh_name']}有{$w_arr['count_num']}个预警商品; \n\n";
                        $msg_tip .= "> [{$w_arr['wh_name']}]({$url}&warehouse[0]={$w_key})\n\n";

                        //-/ 商品列表
                        foreach ($w_arr['list'] as $lkey => $larr) {
                            $lkey = $lkey + 1;
                            if ($lkey <= 10) {
                                $msg_tip .= ">序号{$lkey}   {$larr['goods_name']}  {$larr['goods_sn']}    库存量{$larr['store_num']}\n\n";
                            } else {
                                $num_g = $w_arr['count_num'] - 10;
                                $msg_tip .= ">...(还有{$num_g}个商品~)\n\n";
                                break;
                            }

                        }

                        //-/ 发送信息
                        $w_webhook = $this->arr_robot[$w_key];
                        $flag_w = self::dispose_post_data($w_webhook, $msg_tip, 'markdown');
                        $flag_w && $result['msg'] .= "{$w_key}仓库预警成功；";
                    }
                }
            }
        
        }
        
        $end = microtime(true);
        $result['time'] = $end - $start;
        exit( json_encode($result) );
        
    }
    
    /**
     * 处理webhook数据
     * @param string $webhook 发送地址;
     * @param string $str_tip 提示信息;
     */
    private function dispose_post_data($webhook='', $str_tip='', $msgtype='link') {
        $flag = false;

        /// 数据
        switch ($msgtype) {
            case 'link':
                $data = array(
                    "msgtype" => "link",
                    "link" => array(
                        "text" => $str_tip,
                        "title" => "定时预警商品汇总",
                        "picUrl" => "",
                        "messageUrl" => $this->url_report
                    )
                );
                break;
    
            case 'markdown':
                $data = array(
                    "msgtype" => "markdown",
                    "markdown" => array(
                    "title" => "及时预警商品列表",
                    "text" => $str_tip
                    )
                );
                break;
        }
    
        if( empty($data) ) {
            return $flag;
        }
        $json_data = json_encode($data);
    
        /// 调用
        // $result = {"errcode":0,"errmsg":"ok"};
        $result = self::request_by_curl($webhook, $json_data);
        $arr_result = json_decode($result, true);
        if( !empty($arr_result) && $arr_result['errcode'] == 0 ) {
            $flag = true;
        }
    
        return $flag;
    }
    
    /**
     * webhook
     * @param string $remote_server URL路径
     * @param string $post_string json数据
     */
    private function request_by_curl($remote_server, $post_string) {
        /// curl初始化
        $ch = curl_init();
        ///
        /// curl设置
        curl_setopt($ch, CURLOPT_URL, $remote_server);
        curl_setopt($ch, CURLOPT_POST, 1);
        //-/ 在尝试连接时等待的秒数。设置为0，则无限等待;
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        //-/ 设置 HTTP 头字段的数组。格式： array('Content-type: text/plain', 'Content-length: 100');
        curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
        //-/ TRUE 将curl_exec()获取的信息以字符串返回，而不是直接输出;
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //-/ 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
        curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
        ///
        /// curl执行
        $data = curl_exec($ch);
        ///
        /// curl关闭
        curl_close($ch);
        ///
        return $data;
    }
    
    /**
     * 获取SQL语句
     * @param array $filter 过滤参数数组;
     * @param string $sql_type sql类型;
     */
    private function get_sql( $filter = array(), $sql_type = '' ) {
        $arr_sql = array();
        $sql = '';
    
        switch ( $sql_type ){
            /// 定时预警/及时预计
            case "timing_warn":
                $where_tw = '';
                //-/ 预警数量
                $default_num = $filter['default_num'];
                //-/ 仓库字串
                $str_wid = $filter['str_wid'];
                $date_opt = date('Y-m-d');
                $time_opt = strtotime( $date_opt ) - date('Z');
                $where_tw .= "
                    IFNULL(gs.practical_num, 0) <= IFNULL(gsc.set_val, {$default_num})
                    AND gsr.id IS NULL
                    AND gs.wid IN ({$str_wid})
                    AND g.is_on_sale = 1
                    AND g.is_delete = 0
                ";
                $where_tw_sum = "
                    IFNULL(gs.practical_num, 0) <= IFNULL(gsc.set_val, {$default_num})
                    AND gs.wid IN ({$str_wid})
                    AND g.is_on_sale = 1
                    AND g.is_delete = 0
                ";
    
                /// 添加数量
                $sql_it = "
                    INSERT INTO sdx_gstore_record (
                        goods_id,
                        goods_name,
                        goods_sn,
                        wid,
                        store_num,
                        create_time
                    )
                    SELECT
                        g.goods_id,
                        g.goods_name,
                        g.goods_sn,
                        gs.wid,
                        IFNULL(gs.practical_num, 0) AS store_num,
                        (UNIX_TIMESTAMP( NOW() )-28800) AS create_time
                    FROM
                        sdx_goods g
                    INNER JOIN sdx_goods_storage gs ON gs.goods_id = g.goods_id
                        AND gs.wid IN ({$str_wid})
                    LEFT JOIN sdx_gstore_config gsc ON gsc.set_key = g.goods_sn
                        AND gsc.set_type = gs.wid
                        AND gsc.set_type IN ({$str_wid})
                    LEFT JOIN sdx_warehouse wh ON wh.id = gs.wid
                    LEFT JOIN sdx_gstore_record gsr ON gsr.goods_id = g.goods_id
                        AND gsr.wid = gs.wid
                        AND gsr.wid IN ({$str_wid})
                        AND gsr.create_time >= {$time_opt}
                    WHERE {$where_tw}
                ";
                $arr_sql['sql_it'] = $sql_it;
    
                /// 预警个数
                $sql_count = "
                    SELECT
                        gs.wid,
                        wh.`name`AS wh_name,
                        COUNT(g.goods_id) AS count_num
                    FROM
                        sdx_goods g
                    INNER JOIN sdx_goods_storage gs ON gs.goods_id = g.goods_id
                        AND gs.wid IN ({$str_wid})
                    LEFT JOIN sdx_gstore_config gsc ON gsc.set_key = g.goods_sn
                        AND gsc.set_type = gs.wid
                        AND gsc.set_type IN ({$str_wid})
                    LEFT JOIN sdx_warehouse wh ON wh.id = gs.wid
                    LEFT JOIN sdx_gstore_record gsr ON gsr.goods_id = g.goods_id
                        AND gsr.wid = gs.wid
                        AND gsr.wid IN ({$str_wid})
                        AND gsr.create_time >= {$time_opt}
                    WHERE {$where_tw}
                    GROUP BY gs.wid
                ";
                $arr_sql['sql_count'] = $sql_count;
                
                /// 定时预警汇总
                $sql_count_sum = "
                    SELECT
                		gs.wid,
                		wh.`name`AS wh_name,
                		COUNT(g.goods_id) AS count_num
                    FROM
                    	sdx_goods g
                    INNER JOIN sdx_goods_storage gs ON gs.goods_id = g.goods_id
                    	AND gs.wid IN ({$str_wid})
                    LEFT JOIN sdx_gstore_config gsc ON gsc.set_key = g.goods_sn
                		AND gsc.set_type = gs.wid
                		AND gsc.set_type IN ({$str_wid})
                    LEFT JOIN sdx_warehouse wh ON wh.id = gs.wid
                    WHERE {$where_tw_sum}
                    GROUP BY gs.wid
                ";
                $arr_sql['sql_count_sum'] = $sql_count_sum;
    
                /// 预警商品列表
                $sql_warning = "
                    SELECT
                        g.goods_id,
                        g.goods_name,
                        g.goods_sn,
                        gs.wid,
                        wh.`name` AS wh_name,
                        IFNULL(gs.practical_num, 0) AS store_num,
                        IFNULL(gsc.set_val, {$default_num}) AS warn_num
                    FROM
                        sdx_goods g
                    INNER JOIN sdx_goods_storage gs ON gs.goods_id = g.goods_id
                        AND gs.wid IN ({$str_wid})
                    LEFT JOIN sdx_gstore_config gsc ON gsc.set_key = g.goods_sn
                        AND gsc.set_type = gs.wid
                        AND gsc.set_type IN ({$str_wid})
                    LEFT JOIN sdx_warehouse wh ON wh.id = gs.wid
                    LEFT JOIN sdx_gstore_record gsr ON gsr.goods_id = g.goods_id
                        AND gsr.wid = gs.wid
                        AND gsr.wid IN ({$str_wid})
                        AND gsr.create_time >= {$time_opt}
                    WHERE {$where_tw}
                ";
                $arr_sql['sql_warning'] = $sql_warning;
                break;
    

        }
    
        $arr_sql['sql'] = $sql;
        return $arr_sql;
    }
    
}